package encryption;


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.*;

import sun.misc.*;
import java.text.Normalizer;

public class Hash {
	private static final String SHA1_PRNG = "SHA1PRNG";
	
	public static String getHashSalt(String password, byte[] salt, String hashName)throws NoSuchAlgorithmException, UnsupportedEncodingException{
		MessageDigest digest = MessageDigest.getInstance(hashName);
		digest.reset();
		digest.update(salt);
		//to be analyzed ; what is the importance of adding UTF-8 and why is try catch a vulnerability 
		byte[] input = digest.digest(password.getBytes("UTF-8"));
		
		//byte[] input = digest.digest(password.getBytes());
		for(int i=0; i<100000; i++){
			digest.reset();
			input = digest.digest(input);
		}
		String base64 =byteToBase64(input);
		String normalizedInput=Normalizer.normalize(base64, Normalizer.Form.NFC);
		return normalizedInput;
	}
	
	public static String getFastHashSalt(String password, byte[] salt, String hashName)throws NoSuchAlgorithmException, UnsupportedEncodingException{
		MessageDigest digest = MessageDigest.getInstance(hashName);
		digest.reset();
		digest.update(salt);
		 
		byte[] input = digest.digest(password.getBytes("UTF-8"));
		
		//byte[] input = digest.digest(password.getBytes());
			digest.reset();
			input = digest.digest(input);
			
		String base64 =byteToBase64(input);
		String normalizedInput=Normalizer.normalize(base64, Normalizer.Form.NFC);
		return normalizedInput;
	}

	//we need to check if the sRandom needs to be final on all the app or not
	public static byte[] getSalt(int byteSize){
		SecureRandom sRandom__;
		 try {
			 sRandom__ = SecureRandom.getInstance( SHA1_PRNG );
		    } catch ( NoSuchAlgorithmException e ) {
		        throw new Error(e);
		    }
			
		// 8-bytes usually 
	    final byte [] bytes = new byte[ byteSize ];
	    
	    // Get the next 64 random bits. Forces SecureRandom
	    // to seed itself before returning the bytes.
	    sRandom__.nextBytes(bytes);
	    
	    return bytes;
		
	}
	
	public static String getHash(String text, String hashName) throws UnsupportedEncodingException, NoSuchAlgorithmException{
		MessageDigest digest = MessageDigest.getInstance(hashName);
		digest.reset();
		byte[] input = digest.digest(text.getBytes("UTF-8"));
		String base64 =byteToBase64(input);
		String normalizedInput=Normalizer.normalize(base64, Normalizer.Form.NFC);
		return normalizedInput;
	}
	
	public static String byteToBase64(byte [] bytes){
		BASE64Encoder encoder = new BASE64Encoder();
		return encoder.encode(bytes);
	}
	
	public static byte[] base64ToByte(String data) throws IOException{
		BASE64Decoder decoder = new BASE64Decoder();
		return decoder.decodeBuffer(data);
	}
	
	public static void main(String [] args) throws NoSuchAlgorithmException, UnsupportedEncodingException{
		byte [] salt = Hash.getSalt(8);
		//Hash h1 = new Hash();
		System.out.println(Hash.getHashSalt(getHash("Nada","SHA-1"),salt, "SHA-1"));
		System.out.println(Hash.byteToBase64(salt));
		
		
	}
}